/**
 * 字母收集
 *
 * 描述
 * 有一个 n∗m 的矩形方阵，每个格子上面写了一个小写字母。
 * 小红站在矩形的左上角，她每次可以向右或者向下走，走到某个格子上就可以收集这个格子的字母。
 * 小红非常喜欢 "love" 这四个字母。她拿到一个 l 字母可以得 4 分，拿到一个 o 字母可以得 3 分，
 * 拿到一个 v 字母可以得 2 分，拿到一个 e 字母可以得 1 分。
 * 她想知道，在最优的选择一条路径的情况下，她最多能获取多少分？
 *
 * 输入描述：
 * 1≤n,m≤500
 * 接下来的
 * n 行 每行一个长度为 m 的、仅有小写字母构成的字符串，代表矩形方阵。
 *
 * 输出描述：
 * 小红最大可能的得分。
 */

import java.util.Scanner;

/**
 * 这一题典型的动态规划
 * dp[i][j] : 走到 i j 位置的最大分数
 * 时间复杂度 : O(n ^ 2)
 * 空间复杂度 : O(n ^ 2)
 */

public class Main {
    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);

        // 行数 和 列数
        int n = in.nextInt(), m = in.nextInt();

        // 这里记得要去除换行符
        in.nextLine();

        // 为了后面 dp 好映射, 我们多开辟一个空间, 第一个空间不使用
        // 字符数组
        char[][] nums = new char[n + 1][m + 1];

        // 动态规划
        int[][] dp = new int[n + 1][m + 1];

        // 这里将输入的字符串存入数组
        for (int i = 1; i <= n; i++) {

            // 输入字符串
            char[] s = in.nextLine().toCharArray();

            for (int j = 1; j <= m; j++) {

                // 注意映射关系
                nums[i][j] = s[j - 1];
            }
        }

        // 动态规划
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {

                // 这里正常走路就可以了
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1])
                        + getGrade(nums[i][j]);
            }
        }

        System.out.println(dp[n][m]);
    }

    // 获取分数
    public static int getGrade(char c) {

        // 使用 switch 来筛选分数
        switch (c) {
            case 'l':
                return 4;
            case 'o':
                return 3;
            case 'v':
                return 2;
            case 'e':
                return 1;
            default:
                return 0;
        }
    }
}